package com.zw.pdm.module.production.service;

import com.zw.pdm.constant.Constant;
import com.zw.pdm.entity.basic.Verify;
import com.zw.pdm.entity.production.MakeChange;
import com.zw.pdm.entity.production.MakePlan;
import com.zw.pdm.entity.production.MakeSheet;
import com.zw.pdm.entity.rep.Change;
import com.zw.pdm.entity.rep.Sheet;
import com.zw.pdm.entity.rep.VerifyProcess;
import com.zw.pdm.module.basic.mapper.OrgMapper;
import com.zw.pdm.module.basic.mapper.VerifyMapper;
import com.zw.pdm.module.basic.repository.OrgRepository;
import com.zw.pdm.module.production.mapper.MakeChangeMapper;
import com.zw.pdm.module.production.mapper.MakePlanMapper;
import com.zw.pdm.module.production.mapper.MakeResultMapper;
import com.zw.pdm.module.production.mapper.MakeSheetMapper;
import com.zw.pdm.module.production.model.MakeChangeModel;
import com.zw.pdm.module.production.model.MakePlanModel;
import com.zw.pdm.module.production.repository.MakeChangeRepository;
import com.zw.pdm.module.production.repository.MakePlanRepository;
import com.zw.pdm.module.production.repository.MakeSheetRepository;
import com.zw.pdm.module.report.mapper.ChangeMapper;
import com.zw.pdm.module.report.mapper.PlanMapper;
import com.zw.pdm.module.report.mapper.SheetMapper;
import com.zw.pdm.module.report.mapper.VerifyProcessMapper;
import com.zw.pdm.module.report.repository.ChangeRepository;
import com.zw.pdm.module.report.repository.PlanRepository;
import com.zw.pdm.module.report.repository.SheetRepository;
import com.zw.pdm.module.report.repository.VerifyProcessRepository;
import com.zw.pdm.module.system.service.LogService;
import com.zw.pdm.util.CommonUtils;
import com.zw.pdm.util.FileUtils;
import com.zw.pdm.util.ShiroUtils;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.zw.pdm.constant.Constant.STATUS_COMMIT;
import static com.zw.pdm.util.BeanUtil.copy;


/**
 * @author mayongfeng
 * @version 1.0.0
 * @ClassName ProductionListService.java
 * @Description TODO
 * @createTime 2020年10月06日 16:43:00
 */
@Service
@SuppressWarnings("all")
public class ProductionListService {

    @Autowired
    private MakeSheetMapper makeSheetMapper;
    @Autowired
    private MakeSheetRepository makeSheetRepository;
    @Autowired
    private MakePlanMapper makePlanMapper;
    @Autowired
    private MakePlanRepository makePlanRepository;
    @Autowired
    private MakeChangeMapper makeChangeMapper;
    @Autowired
    private MakeChangeRepository makeChangeRepository;
    @Autowired
    private MakeResultMapper makeResultMapper;
    /***************************************************************/
    @Autowired
    private SheetMapper sheetMapper;
    @Autowired
    private SheetRepository sheetRepository;
    @Autowired
    private PlanMapper planMapper;
    @Autowired
    private PlanRepository planRepository;
    @Autowired
    private OrgRepository orgRepository;
    @Autowired
    private OrgMapper orgMapper;
    @Autowired
    private VerifyMapper verifyMapper;
    @Autowired
    private VerifyProcessRepository verifyProcessRepository;
    @Autowired
    private VerifyProcessMapper verifyProcessMapper;
    @Autowired
    private ChangeRepository changeRepository;
    @Autowired
    private ChangeMapper changeMapper;

    @Value("${user.upload.path}")
    private String uploadPath;

    @Autowired
    private LogService logService;

    /**
     * myf制作件清单列表
     */
    public List<MakeSheet> findWithReportList(MakeSheet sheet, Integer i) {
        //获得用户Id
        sheet.setPostUserId(ShiroUtils.getUserId());
        //获得用户账号
        sheet.setCreateCodeTwo(ShiroUtils.getLoginName());
        //判断管理部门数量
        if (i == 1) {
            return makeSheetMapper.findEqIdWithMakeSheetReportList(sheet);
        } else {
            return makeSheetMapper.findInIdWithMakeSheetReportList(sheet);
        }
    }

    /**
     * myf按ID删除制作件清单主表及其明细表
     * 如果删除的为变更单，则原变更计划可再次变更。
     */
    public int delSheetById(Integer id) {
        logService.saveLog("删除制作件清单", "制作件ID：" + id);
        MakeSheet makeSheet = makeSheetRepository.getOne(id);
        //判断是原始单还是变更单（1=原始单，2=变更单）
        if (makeSheet.getSheetType() == 2) {
            //通过sheetId查询变更表的数据
            List<MakeChange> changes = makeChangeMapper.findMakeChangeBySheetId(id);
            //循环将每条数据的变更状态置为初始值
            for (MakeChange change : changes) {
                if (change.getChangeId() != null) {
                    MakeChange makeChange = makeChangeRepository.getOne(change.getChangeId());
                    makeChange.setChangeStatus(0);
                    makeChangeRepository.saveAndFlush(makeChange);
                } else if (change.getPlanId() != null) {
                    MakePlan makePlan = makePlanRepository.getOne(change.getPlanId());
                    makePlan.setChangeStatus(0);
                    makePlanRepository.saveAndFlush(makePlan);
                }
            }
            //通过Id修改明细表make_change的此条数据的删除状态1=删除，0=默认正常
            makeChangeMapper.updateMakeChaIsDelBySheetId(id, Constant.STATUS_NORMAL);
            //判断是原始单还是变更单（1=原始单，2=变更单）
        } else if (makeSheet.getSheetType() == 1) {
            //通过Id修改明细表make_plan的此条数据的删除状态1=删除，0=默认正常
            makePlanMapper.updateMakePlanIsDelBySheetId(id, Constant.STATUS_NORMAL);
        }
        //修改主表的删除状态
        return makeSheetMapper.updateMakeSheetIsDelById(id, Constant.STATUS_NORMAL);
    }

    /**
     * 提交制作件清单
     */
    @Transactional(rollbackFor = Exception.class)
    public int commitMakeSheetById(Integer id) {
        logService.saveLog("提交制作件清单", "制作件清单ID：" + id);
        MakeSheet makeSheet = makeSheetRepository.getOne(id);
        //判断提交列表的提交状态1=未提交，2=已提交，3=被驳回，4=撤消，5=全部审核通过，
        if (makeSheet.getStatus() == STATUS_COMMIT) {
            return 1;
        }
        // 查询审核配置
        Verify verify = new Verify();
        List<Verify> verifyList = verifyMapper.findMakeSheetByCondition(verify);
        // 生成审核记录
        for (int i = 0; i < verifyList.size(); i++) {
            //创建审核记录表的对象
            VerifyProcess vp = new VerifyProcess();
            //制作件表的主ID
            vp.setMakeSheetId(makeSheet.getId());
            //审核的排序字段
            vp.setOrderNo(verifyList.get(i).getOrderNo());
            //是否最后审核 0=否， 1=是
            vp.setComp(verifyList.get(i).getComp());
            //判断是否是首次审核
            if (i == 0) {
                /** 当前标记 0=非 1=是  */
                vp.setCur(1);
                /** 是否为起始审核 0=否 1=是 */
                vp.setStart(1);
            } else {
                vp.setCur(0);
                vp.setStart(0);
            }
            /** 状态 0=被驳回，1=未审核，2=已审核 */
            vp.setStatus(1);
            /** 审核人ID */
            vp.setVerifier(verifyMapper.findVerifier(ShiroUtils.getUserId(), verifyList.get(i).getPost()));
            verifyProcessRepository.save(vp);
        }
        //通过Id修改主表的status的状态为2=已提交
        return makeSheetMapper.updateMakeStatusAndRejectReasonById(id, null, STATUS_COMMIT);
    }

    /**
     * 按ID删除制作件详细表的数据
     */
    public int delPlanById(Integer id) {
        logService.saveLog("删除制作件清单明细", "makePlan的计划ID" + id);
        return makePlanMapper.updateIsDelById(id, Constant.STATUS_NORMAL);
    }

    /**
     * 上传计划附件
     */
    public MakePlan uploadWithPlan(MakePlan plan, MultipartFile file) {
        if (null != file) {
            MakePlan p = makePlanRepository.getOne(plan.getId());
            plan.setUploadTime(new Date());
            StringBuffer pathPart = new StringBuffer();
            pathPart.append(p.getSheetId());
            pathPart.append("/");
            pathPart.append(p.getId());
            pathPart.append("/");
            String fileName = FileUtils.upload(file, uploadPath + pathPart.toString());
            if (CommonUtils.isNotNull(fileName)) {
                p.setUrl("/files/" + pathPart.toString() + fileName);
                logService.saveLog("上传附件", "名称：" + fileName);
                return makePlanRepository.saveAndFlush(p);
            }
        }
        return null;
    }

    /**
     * 修改制作件清单
     */
    public int editMake(MakeSheet makeSheet, Integer[] makePlanId, String[] drawNo, Integer[] drawNum, String[] drawName, String[] makeType, String[] remark) {
        MakeSheet target = makeSheetRepository.getOne(makeSheet.getId());
        target.setPostTel(makeSheet.getPostTel());
        target.setSpecial(makeSheet.getSpecial());
        target.setSpecialId(makeSheet.getSpecialId());
        target.setPart(makeSheet.getPart());
        target.setPartId(makeSheet.getPartId());
        makeSheetRepository.saveAndFlush(target);
        for (int i = 0; i < makePlanId.length; i++) {
            MakePlan makePlan = makePlanRepository.getOne(makePlanId[i]);
            makePlan.setDrawNo(drawNo[i]);
            makePlan.setDrawName(drawName[i]);
            makePlan.setDrawNum(drawNum[i]);
            makePlan.setMakeType(makeType[i]);

//            if ("装配件".equals(CommonUtils.trimAll(makeType[i]))) {
//                makePlan.setMakeType(CommonUtils.trimAll(makeType[i]));
//                makePlan.setQuality(makeType[i]);
//            } else {
//                makePlan.setMakeType("加工件");
//                makePlan.setQuality(makeType[i]);
//            }

            if (remark.length > 0) {
                makePlan.setRemark(remark[i]);
            }
            makePlanRepository.saveAndFlush(makePlan);
        }
        logService.saveLog("修改制作件清单", "制作件清单ID：" + makeSheet.getId());
        return 1;
    }

    /**
     * 按 IDS 查询计划
     */
    public List<MakePlan> findMakePlanByIds(String ids) {
        return makePlanMapper.findMakeByIds(ids);
    }

    /**
     * 按 IDS 查询变更
     */
    public List<MakeChange> findMakeChangeByIds(String ids) {
        return makeChangeMapper.findMakeChangeByIds(ids);
    }

    /**
     * 生成变更批次号
     */
    private void genChangeBatchNo(Sheet sheet) {
        Sheet st = sheetMapper.findChangeFirstByBatchNo(sheet.getProCode());
        if (st == null) {
            sheet.setBatchNo(sheet.getProCode() + "R001");
        } else {
            int no = Integer.parseInt(CommonUtils.substring(st.getBatchNo(), st.getProCode().length() + 1));
            sheet.setBatchNo(sheet.getProCode() + "R" + CommonUtils.intToString(no + 1, 3));
        }
    }

    /**
     * 生成变更制作件请单主表
     */
    private MakeSheet genChangeSheet(MakeSheet st) {
        MakeSheet sheet = makeSheetRepository.getOne(st.getId());
        MakeSheet target = new MakeSheet();
        copy(sheet, target);
        target.setId(null);
        /** 状态 1=未提交，2=已提交，3=被驳回，4=撤消，5=全部审核通过，6=已确认*/
        target.setStatus(1);
        /** 表单类型 1=原始，2=变更*/
        target.setSheetType(2);
        /** 是否可以变更  0=否，1=是*/
        target.setMayChange(0);
        /** 接收标识 0=未接收，1=已接收*/
        target.setReceiveStatus(0);
        /** 制作件主表ID*/
        target.setSheetId(st.getId());
        /** 提报人电话*/
        target.setPostTel(st.getPostTel());
        /** 接收人*/
        target.setReceiveName(null);
        target.setPostUserId(ShiroUtils.getUserId());
        target.setCreateNameOne(ShiroUtils.getUser().getName());
        target.setCreateNameTwo(ShiroUtils.getUser().getName());
        target.setCreateTime(new Date());
        return makeSheetRepository.save(target);
    }

    /**
     * 保存制作件变更单
     */
    @Transactional(rollbackFor = Exception.class)
    public int saveOutChange(MakeSheet st,
                             String[] changeReason, Integer[] planId,
                             String[] afterDrawNo, Integer[] afterDrawNum, String[] afterDrawName,
                             String[] afterMakeType, String[] afterRemark, String[] afterUrl, Integer[] orderNum, Integer[] technologyChange) {
        MakeSheet makeSheet = genChangeSheet(st);
        /** 查询原来的制作清单*/
        MakeSheet src = makeSheetRepository.getOne(st.getId());
        logService.saveLog("制作件计划单变更", "原制作件ID：" + src.getId() + " 新制作件ID：" + st.getId());
        /**前端一共传过来多少条数据需要处理*/
        Integer planNum = planId.length;
        for (int i = 0; i < planNum; i++) {
            /** 创建变更表的对象*/
            MakeChange change = new MakeChange();
            /** 判断原始单还是变更单sheetType 1=原始单，2=变更单*/
            if (src.getSheetType() == 1) {
                originalOrderChange(planId, afterDrawNo, afterDrawNum, afterDrawName, afterMakeType, afterRemark, afterUrl, technologyChange, i, change);

            } else if (src.getSheetType() == 2) {
                changeOrderChange(planId, afterDrawNo, afterDrawNum, afterDrawName, afterMakeType, afterRemark, afterUrl, technologyChange, i, change);
            }
            /** 变更的参数保存数据库*/
            addChanges(changeReason[i], afterDrawNo[i], afterDrawNum[i], afterDrawName[i], afterMakeType[i], afterRemark, afterUrl, makeSheet, i, change, orderNum[i]);
        }
        return 1;
    }


    /**
     * @Author mayongfeng
     * @Description //TODO 原始单变更时的增删改查
     * @Date 12:55 2020/10/30
     * @Param [planId, afterDrawNo, afterDrawNum, afterDrawName, afterMakeType, afterRemark, afterUrl, technologyChange, i, change]
     * @return void
     **/
    private void originalOrderChange(Integer[] planId, String[] afterDrawNo, Integer[] afterDrawNum, String[] afterDrawName, String[] afterMakeType, String[] afterRemark, String[] afterUrl, Integer[] technologyChange, int i, MakeChange change) {
        /** 判断planId是否为0如果planId=0说明这条数据是变更新增的数据*/
        if (planId[i] != 0) {
            /** 判断填写的数据对比是否更改过如：比对时发现是未更改说明这条数据没有改变*/
            MakePlan plan = makePlanRepository.getOne(planId[i]);
            /** 判断technologyChange是否等于2，如果technologyChange=2说明这条数据是变更删除*/
            if (technologyChange[i] != 2) {
                /** 判断数据库每个字段的值和前端传过来的每个字段的值进行比对相等说明没有修改*/
                if (plan.getDrawNo().equals(afterDrawNo[i])
                        && plan.getDrawName().equals(afterDrawName[i])
                        && plan.getDrawNum() == afterDrawNum[i]
                        && plan.getMakeType().equals(afterMakeType[i])
                        && (plan.getRemark()==null? "":plan.getRemark()).equals(afterRemark.length > 0 ? CommonUtils.isEmpty(afterRemark[i]) ? afterRemark[i] : "" : "")
                        && (plan.getUrl()==null?"":plan.getUrl()).equals(afterUrl.length > 0  ? CommonUtils.isEmpty(afterUrl[i]) ? afterUrl[i] : "" : "")) {
                        /** 此数据为不变更的数据*/
                        change.setTechnologyChange(Constant.NOT_CHANGE);
                    rawData(change, plan);
                }else {
                    /** 此数据为变更数据*/
                    change.setTechnologyChange(Constant.CHANGE_CHANGE);
                    rawData(change, plan);

                }

            } else {
                change.setTechnologyChange(Constant.NOT_CHANGE);
                rawData(change, plan);
                /** 此数据为变更删除数据*/
                change.setTechnologyChange(Constant.CHANGE_DEL);
            }
        } else {
            /** 此数据为变更增加数据*/
            change.setTechnologyChange(Constant.CHANGE_ADD);
        }
    }

    /** 将原始数据make_plan表赋值给make_change表里面*/
    private void rawData(MakeChange change, MakePlan plan) {
        plan.setChangeStatus(1);
        makePlanRepository.saveAndFlush(plan);
        copy(plan, change);
        change.setPlanId(plan.getId());
    }

    /**
     * @Author mayongfeng
     * @Description //TODO 变更单的增删改
     * @Date 12:55 2020/10/30
     * @Param [planId, afterDrawNo, afterDrawNum, afterDrawName, afterMakeType, afterRemark, afterUrl, technologyChange, i, change]
     * @return void
     **/
    private void changeOrderChange(Integer[] planId, String[] afterDrawNo, Integer[] afterDrawNum, String[] afterDrawName, String[] afterMakeType, String[] afterRemark, String[] afterUrl, Integer[] technologyChange, int i, MakeChange change) {
        /** 判断planId是否为0如果planId=0说明这条数据是变更新增的数据*/
        if (planId[i] != 0) {
            /** 判断technologyChange是否等于2，如果technologyChange=2说明这条数据是变更删除*/
            MakeChange c = makeChangeRepository.getOne(planId[i]);
            if(technologyChange[i] !=2){
                /** 判断数据库每个字段的值和前端传过来的每个字段的值进行比对相等说明没有修改*/
                if (c.getAfterDrawNo().equals(afterDrawNo[i])
                        && c.getAfterDrawName().equals(afterDrawName[i])
                        && c.getAfterDrawNum() == afterDrawNum[i]
                        && c.getAfterMakeType().equals(afterMakeType[i])
                        && (c.getAfterRemark()==null ? "" : c.getAfterRemark()==""? "" : c.getAfterRemark()).equals(afterRemark.length > 0 ? CommonUtils.isNotEmpty(afterRemark[i]) ? afterRemark[i] : "" : "")
                        && (c.getAfterUrl()==null?"":c.getAfterUrl()).equals(afterUrl.length > 0  ? CommonUtils.isEmpty(afterUrl[i]) ? afterUrl[i] : "" : "")) {
                    /** 此数据为不变更的数据*/
                    change.setTechnologyChange(Constant.NOT_CHANGE);
                    c.setChangeStatus(1);
                    changDate(change, c);
                }else {
                    changDate(change, c);
                    change.setTechnologyChange(Constant.CHANGE_CHANGE);
                }

            }else{
                /** 此数据为变更删除数据*/
                change.setTechnologyChange(Constant.CHANGE_DEL);
                changDate(change, c);
            }

        } else {
            /** 此数据为变更增加数据*/
            change.setTechnologyChange(Constant.CHANGE_ADD);
        }
    }

    /** 将变更后的数据作为原数据放到change表的变更前字段*/
    private void changDate(MakeChange change, MakeChange c) {
        makeChangeRepository.saveAndFlush(c);
        change.setDrawNo(c.getAfterDrawNo());
        change.setDrawName(c.getAfterDrawName());
        change.setDrawNum(c.getAfterDrawNum());
        change.setMakeType(c.getAfterMakeType());
        change.setRemark(c.getAfterRemark());
        change.setUrl(c.getAfterUrl());
        change.setPlanId(c.getPlanId());
        change.setChangeId(c.getId());
        change.setOrderNum(c.getOrderNum());
    }

    /**
     * 变更的参数保存到数据库表make_change
     */
    private void addChanges(String changeReason, String afterDrawNo, Integer afterDrawNum, String afterDrawName, String afterMakeType, String[] afterRemark, String[] afterUrl, MakeSheet makeSheet, int i, MakeChange change, Integer orderNum) {
        change.setId(null);
        change.setChangeStatus(0);
        change.setSheetId(makeSheet.getId());
        change.setCreateTime(new Date());
        change.setIsDel(Constant.STATUS_DELETE);
        change.setAfterDrawNo(afterDrawNo);
        change.setAfterDrawName(afterDrawName);
        change.setAfterDrawNum(afterDrawNum);
        change.setOrderNum(orderNum);
        if ("装配件".equals(CommonUtils.trimAll(afterMakeType))) {
            change.setAfterMakeType(CommonUtils.trimAll(afterMakeType));
            change.setAfterQuality(afterMakeType);
        } else {
            change.setAfterMakeType("加工件");
            change.setAfterQuality(afterMakeType);
        }
        if (afterRemark.length > 0) {
            change.setAfterRemark(afterRemark[i]);
        }
        change.setChangeReason(changeReason);
        change = makeChangeRepository.save(change);
        if (afterUrl.length > 0 && CommonUtils.isNotEmpty(afterUrl[i])) {
            StringBuffer dir = new StringBuffer();
            dir.append(uploadPath).append(makeSheet.getId()).append("/c/").append(change.getId()).append("/");
            try {
                org.apache.commons.io.FileUtils.moveToDirectory(new File(afterUrl[i]), new File(dir.toString()), true);
            } catch (IOException e) {
                e.printStackTrace();
            }
            StringBuffer srcPart = new StringBuffer();
            srcPart.append(uploadPath).append(ShiroUtils.getLoginName()).append("/temp/");
            StringBuffer targetPart = new StringBuffer();
            targetPart.append("/files/").append(makeSheet.getId()).append("/c/").append(change.getId()).append("/");
            change.setAfterUrl(afterUrl[i].replace(srcPart.toString(), targetPart.toString()));
            change.setUploadTime(new Date());
            makeChangeRepository.save(change);
        }
    }


    /**
     * 按ID删除变更计划
     */
    public int delChangeById(Integer id) {
        return changeMapper.delById(id);
    }

    /**
     * 上传变更计划附件
     */
    public Change uploadWithChange(Change change, MultipartFile file) {
        if (null != file) {
            Change p = changeRepository.getOne(change.getId());
            StringBuffer sb = new StringBuffer();
            sb.append(uploadPath);
            sb.append(p.getSheetId());
            sb.append("/c/");
            sb.append(p.getId());
            sb.append("/");
            String fileName = FileUtils.upload(file, sb.toString());
            if (CommonUtils.isNotNull(fileName)) {
                StringBuffer url = new StringBuffer();
                url.append("/files/");
                url.append(p.getSheetId());
                url.append("/c/");
                url.append(p.getId());
                url.append("/");
                url.append(fileName);
                p.setAfterUrl(url.toString());
                logService.saveLog("上传附件", "名称：" + fileName);
                return changeRepository.saveAndFlush(p);
            }
        }
        return null;
    }

    /**
     * 修改制作件变更计划单
     */
    @Transactional
    public int editOutChange(MakeSheet st,
                             String[] changeReason, Integer[] planId,
                             String[] afterDrawNo, Integer[] afterDrawNum, String[] afterDrawName,
                             String[] afterMakeType, String[] afterRemark) {
        MakeSheet makeSheet = makeSheetRepository.getOne(st.getId());
        makeSheet.setPart(st.getPart());
        makeSheet.setPartId(st.getPartId());
        makeSheet.setPostTel(st.getPostTel());
        makeSheet.setSpecial(st.getSpecial());
        makeSheet.setSpecialId(st.getSpecialId());
        makeSheetRepository.saveAndFlush(makeSheet);
        for (int i = 0; i < planId.length; i++) {
            MakeChange change = makeChangeRepository.getOne(planId[i]);
            if(change.getTechnologyChange()==Constant.NOT_CHANGE){
                /** 判断数据库每个字段的值和前端传过来的每个字段的值进行比对相等说明没有修改*/
                if (change.getAfterDrawNo().equals(afterDrawNo[i])
                        && change.getAfterDrawName().equals(afterDrawName[i])
                        && change.getAfterDrawNum() == afterDrawNum[i]
                        && change.getAfterMakeType().equals(afterMakeType[i])
                        && (change.getAfterRemark()==null ? "" : change.getAfterRemark()==""? "" : change.getAfterRemark()).equals(afterRemark.length > 0 ? CommonUtils.isNotEmpty(afterRemark[i]) ? afterRemark[i] : "" : "")) {
                }else {
                    /** 此数据为不变更的数据*/
                    change.setTechnologyChange(Constant.CHANGE_CHANGE);
                }
            }
            change.setAfterDrawNo(afterDrawNo[i]);
            change.setAfterDrawName(afterDrawName[i]);
            change.setAfterDrawNum(afterDrawNum[i]);
            change.setAfterMakeType(afterMakeType[i]);

            if (afterRemark.length > 0) {
                change.setAfterRemark(afterRemark[i]);
            }
            change.setChangeReason(changeReason[i]);
            makeChangeRepository.save(change);
        }
        logService.saveLog("修改制作件清单变更单", "制作件ID：" + makeSheet.getId());
        return 1;
    }

    public int delMakeChangeById(Integer id) {
        return 1;
    }


    /**
     * 按计划单ID查询计划
     */
    public List<MakePlan> findPlanListBySheetId(Integer sheetId) {
        return makePlanMapper.findByMakeSheetId(sheetId);

    }


    /**
     * 按计划单ID查询变更
     */
    public List<MakeChange> findChangeListBySheetId(Integer sheetId) {
        return makeChangeMapper.findBySheetId(sheetId);
    }

    /**
     * 查询管理部门数量
     */
    public Integer countOrgByUserId() {
        return orgMapper.countOrgByUserId(ShiroUtils.getUserId());
    }


    /**
     * 通过ID集合查询result表里原始数据
     */
    public List<MakePlanModel> findMakeResultPlanByIds(String ids) {
        List<MakePlanModel> listMakeReslut = makeResultMapper.findMakeResultPlanByIdsSheet(ids);
        return listMakeReslut;
    }

    /**
     * 通过Id集合查询变更后的result表里数据
     */
    public List<MakeChangeModel> findMakeResultChangeByIds(String ids) {
        List<MakeChangeModel> listMakeChangeResult = makeResultMapper.findMakeResultChangeByIdsSheet(ids);
        return listMakeChangeResult;
    }


    /**************************************************变更后的需求************************************************************************/

    /**
     * 按计划单ID查询计划
     */
    public List<MakePlanModel> modifyFindByMakeSheetId(Integer sheetId) {
        return makePlanMapper.modifyFindByMakeSheetId(sheetId);
    }

    /**
     * 按计划单ID查询变更
     */
    public List<MakeChangeModel> findByMobifySheetId(Integer sheetId) {
        return makeChangeMapper.findByMobifySheetId(sheetId);
    }

    /**
     * 保存制作件变更单
     */
    @Transactional(rollbackFor = Exception.class)
    public int modifySaveChange(MakeSheet st, Integer[] planId,
                             String[] afterDrawNo, Integer[] afterDrawNum, String[] afterDrawName,
                             String[] afterMakeType, String[] afterRemark, String[] afterUrl, Integer[] orderNum, Integer[] technologyChange,Integer[] pid) {
        /** 保存到主表数据*/
        MakeSheet makeSheet = modifyGenChangeSheet(st);
        /** 查询原来的制作清单*/
        MakeSheet src = makeSheetRepository.getOne(st.getId());
        logService.saveLog("制作件清单变更", "原制作件ID：" + src.getId() + " 新制作件ID：" + st.getId());
        /**前端一共传过来多少条数据需要处理*/
        Integer planNum = planId.length;
        for (int i = 0; i < planNum; i++) {
            /** 创建变更表的对象*/
            MakeChange change = new MakeChange();
            /** 判断原始单还是变更单sheetType 1=原始单，2=变更单*/
            if (src.getSheetType() == 1){
                if (modifySavePlan(planId, afterDrawNo, afterDrawNum, afterDrawName, afterMakeType, afterRemark, afterUrl, technologyChange, i, change))
                    continue;
            } else if (src.getSheetType() == 2){
                if (modifySaveMakeChange(planId, afterDrawNo, afterDrawNum, afterDrawName, afterMakeType, afterRemark, afterUrl, technologyChange, i, change))
                    continue;
            }
            /** 变更的参数保存数据库*/
            modifyAddChanges(afterDrawNo[i], afterDrawNum[i], afterDrawName[i], afterMakeType[i], afterRemark, afterUrl, makeSheet, i, change, orderNum[i],pid[i]);
        }
        return makeSheet.getId();
    }

    /**
     * @Author mayongfeng
     * @Description //TODO 变更单的增删改
     * @Date 12:55 2020/10/30
     * @Param [planId, afterDrawNo, afterDrawNum, afterDrawName, afterMakeType, afterRemark, afterUrl, technologyChange, i, change]
     * @return void
     **/
    private boolean modifySaveMakeChange(Integer[] planId, String[] afterDrawNo, Integer[] afterDrawNum, String[] afterDrawName, String[] afterMakeType, String[] afterRemark, String[] afterUrl, Integer[] technologyChange, int i, MakeChange change) {
        /** 判断planId是否为0如果planId=0说明这条数据是变更新增的数据*/
        if (planId[i] != 0) {
            /** 判断technologyChange是否等于2，如果technologyChange=2说明这条数据是变更删除*/
            MakeChange c = makeChangeRepository.getOne(planId[i]);
            if(technologyChange[i] !=2){
                /** 判断数据库每个字段的值和前端传过来的每个字段的值进行比对相等说明没有修改*/
                if (c.getAfterDrawNo().equals(afterDrawNo[i])
                        && c.getAfterDrawName().equals(afterDrawName[i])
                        && c.getAfterDrawNum().intValue() == afterDrawNum[i].intValue()
                        && c.getAfterMakeType().equals(afterMakeType[i])
                        && (c.getAfterRemark()==null ? "" : c.getAfterRemark()==""? "" : c.getAfterRemark()).equals(afterRemark.length > 0 ? CommonUtils.isNotEmpty(afterRemark[i]) ? afterRemark[i] : "" : "")
                        && (c.getAfterUrl()==null?"":c.getAfterUrl()).equals(afterUrl.length > 0  ? CommonUtils.isEmpty(afterUrl[i]) ? afterUrl[i] : "" : "")) {
                    /** 此数据为不变更的数据跳出循环*/
                    return true;
                }else {
                    modifyChangDate(change, c);
                    change.setTechnologyChange(Constant.CHANGE_CHANGE);
                }

            }else{
                /** 此数据为变更删除数据*/
                change.setTechnologyChange(Constant.CHANGE_DEL);
                modifyChangDate(change, c);
            }

        } else {
            /** 此数据为变更增加数据*/
            change.setTechnologyChange(Constant.CHANGE_ADD);
        }
        return false;
    }


    /**
     * @Author mayongfeng
     * @Description //TODO 原始单变更时的增删改查
     * @Date 12:55 2020/10/30
     * @Param [planId, afterDrawNo, afterDrawNum, afterDrawName, afterMakeType, afterRemark, afterUrl, technologyChange, i, change]
     * @return void
     **/
    private boolean modifySavePlan(Integer[] planId, String[] afterDrawNo, Integer[] afterDrawNum, String[] afterDrawName, String[] afterMakeType, String[] afterRemark, String[] afterUrl, Integer[] technologyChange, int i, MakeChange change) {
        if (planId[i] != 0) {
            /** 判断填写的数据对比是否更改过如：比对时发现是未更改说明这条数据没有改变*/
            MakePlan plan = makePlanRepository.getOne(planId[i]);
            /** 判断technologyChange是否等于2，如果technologyChange=2说明这条数据是变更删除*/
            if (technologyChange[i] != 2) {
                /** 判断数据库每个字段的值和前端传过来的每个字段的值进行比对相等说明没有修改*/
                if (plan.getDrawNo().equals(afterDrawNo[i])
                        && plan.getDrawName().equals(afterDrawName[i])
                        && plan.getDrawNum().intValue() == afterDrawNum[i].intValue()
                        && plan.getMakeType().equals(afterMakeType[i])
                        && (null == plan.getRemark()? "":plan.getRemark().trim()).equals(afterRemark.length > 0 ? CommonUtils.isNotEmpty(afterRemark[i]) ? afterRemark[i] : "" : "")
                        && (plan.getUrl()==null?"":plan.getUrl()).equals(afterUrl.length > 0  ? CommonUtils.isEmpty(afterUrl[i]) ? afterUrl[i] : "" : "")) {
                    /** 此数据为不变更的数据跳出循环*/
                    return true;
                }else {
                    /** 此数据为变更数据*/
                    change.setTechnologyChange(Constant.CHANGE_CHANGE);
                    modifyRawData(change, plan);

                }

            } else {
                /** 此数据为变更删除数据*/
                change.setTechnologyChange(Constant.CHANGE_DEL);
                modifyRawData(change, plan);

            }
        } else {
            /** 此数据为变更增加数据*/
            change.setTechnologyChange(Constant.CHANGE_ADD);
        }
        return false;
    }


    /**
     * 生成变更制作件请单主表
     */
    private MakeSheet modifyGenChangeSheet(MakeSheet st) {
        MakeSheet sheet = makeSheetRepository.getOne(st.getId());
        MakeSheet target = new MakeSheet();
        copy(sheet, target);
        target.setId(null);
        /** 状态 1=未提交，2=已提交，3=被驳回，4=撤消，5=全部审核通过，6=已确认*/
        target.setStatus(1);
        /** 表单类型 1=原始，2=变更*/
        target.setSheetType(2);
        /** 是否可以变更  0=否，1=是*/
        target.setMayChange(0);
        /** 接收标识 0=未接收，1=已接收*/
        target.setReceiveStatus(0);
        /** 制作件主表ID*/
        target.setSheetId(st.getId());
        /** 提报人电话*/
        target.setPostTel(st.getPostTel());
        /** 接收人*/
        target.setReceiveName(null);
        target.setReceiveTime(null);
        //拆分状态  0=未拆分，1=已拆分
        target.setRawSplit(0);
        target.setLssueStatus(1);
        target.setPostUserId(ShiroUtils.getUserId());
        target.setCreateNameOne(ShiroUtils.getUser().getName());
        target.setCreateNameTwo(ShiroUtils.getUser().getName());
        target.setCreateTime(new Date());
        return makeSheetRepository.save(target);
    }


    /** 将原始数据make_plan表赋值给make_change表里面*/
    private void modifyRawData(MakeChange change, MakePlan plan) {
        plan.setChangeStatus(1);
        makePlanRepository.saveAndFlush(plan);
        copy(plan, change);
        change.setPlanId(plan.getId());
    }



    /** 将变更后的数据作为原数据放到change表的变更前字段*/
    private void modifyChangDate(MakeChange change, MakeChange c) {
        c.setChangeStatus(1);
        makeChangeRepository.saveAndFlush(c);
        change.setDrawNo(c.getAfterDrawNo());
        change.setDrawName(c.getAfterDrawName());
        change.setDrawNum(c.getAfterDrawNum());
        change.setMakeType(c.getAfterMakeType());
        change.setRemark(c.getAfterRemark());
        change.setUrl(c.getAfterUrl());
        change.setPlanId(c.getPlanId());
        change.setChangeId(c.getId());
        change.setOrderNum(c.getOrderNum());
        change.setPid(c.getPid());
    }


    /**
     * 变更的参数保存到数据库表make_change
     */
    private void modifyAddChanges( String afterDrawNo, Integer afterDrawNum, String afterDrawName, String afterMakeType, String[] afterRemark, String[] afterUrl, MakeSheet makeSheet, int i, MakeChange change, Integer orderNum,Integer pid) {
        change.setId(null);
        change.setChangeStatus(0);
        change.setSheetId(makeSheet.getId());
        change.setCreateTime(new Date());
        change.setIsDel(Constant.STATUS_DELETE);
        change.setAfterDrawNo(afterDrawNo);
        change.setAfterDrawName(afterDrawName);
        change.setAfterDrawNum(afterDrawNum);
        change.setOrderNum(orderNum);
        change.setPid(pid);
        change.setAfterMakeType(afterMakeType);
        if (afterRemark.length > 0) {
            change.setAfterRemark(afterRemark[i]);
        }
        change = makeChangeRepository.save(change);
        if (afterUrl.length > 0 && CommonUtils.isNotEmpty(afterUrl[i])) {
            StringBuffer dir = new StringBuffer();
            dir.append(uploadPath).append(makeSheet.getId()).append("/c/").append(change.getId()).append("/");
            try {
                org.apache.commons.io.FileUtils.moveToDirectory(new File(afterUrl[i]), new File(dir.toString()), true);
            } catch (IOException e) {
                e.printStackTrace();
            }
            StringBuffer srcPart = new StringBuffer();
            srcPart.append(uploadPath).append(ShiroUtils.getLoginName()).append("/temp/");
            StringBuffer targetPart = new StringBuffer();
            targetPart.append("/files/").append(makeSheet.getId()).append("/c/").append(change.getId()).append("/");
            change.setAfterUrl(afterUrl[i].replace(srcPart.toString(), targetPart.toString()));
            change.setUploadTime(new Date());
            makeChangeRepository.save(change);
        }
    }


    /**
     * 提交制作件清单
     */
    @Transactional(rollbackFor = Exception.class)
    public int modifyCommitMakeSheetById(Integer id) {
        logService.saveLog("提交制作件清单", "制作件清单ID：" + id);

        MakeSheet makeSheet = makeSheetRepository.getOne(id);

        //判断提交列表的提交状态1=未提交，2=已提交，3=被驳回，4=撤消，5=全部审核通过，
        if (makeSheet.getStatus() == STATUS_COMMIT) {
            return 1;
        }
        //判断是原始单还是变更单1=原始单 2=变更单
        if(makeSheet.getSheetType()==2){
            List<MakeChange> byMobifySheetIdAll = makeChangeMapper.findByMobifySheetIdAll(makeSheet.getId());
            //判断如果是变更单的话判断原因有没有写，没写原因，在提交时警告许把原因填写了。
            for (MakeChange makeChange : byMobifySheetIdAll) {
                if(null == makeChange.getChangeReason() || makeChange.getChangeReason().equals("")){
                    return -7;
                }

            }

        }


        // 查询审核配置
        Verify verify = new Verify();
        List<Verify> verifyList = verifyMapper.findMakeSheetByCondition(verify);
        // 生成审核记录
        for (int i = 0; i < verifyList.size(); i++) {
            //创建审核记录表的对象
            VerifyProcess vp = new VerifyProcess();
            //制作件表的主ID
            vp.setMakeSheetId(makeSheet.getId());
            //审核的排序字段
            vp.setOrderNo(verifyList.get(i).getOrderNo());
            //是否最后审核 0=否， 1=是
            vp.setComp(verifyList.get(i).getComp());
            //判断是否是首次审核
            if (i == 0) {
                /** 当前标记 0=非 1=是  */
                vp.setCur(1);
                /** 是否为起始审核 0=否 1=是 */
                vp.setStart(1);
            } else {
                vp.setCur(0);
                vp.setStart(0);
            }
            /** 状态 0=被驳回，1=未审核，2=已审核 */
            vp.setStatus(1);
            /** 审核人ID */
            vp.setVerifier(verifyMapper.findVerifier(ShiroUtils.getUserId(), verifyList.get(i).getPost()));
            verifyProcessRepository.save(vp);
        }
        //通过Id修改主表的status的状态为2=已提交
        return makeSheetMapper.updateMakeStatusAndRejectReasonById(id, null, STATUS_COMMIT);
    }

    /**
     * @Author mayongfeng
     * @Date 19:21 2020/12/11
     * @Description 获得重复的图号
     *
     **/
    public List<String> getRepeatDrawNo(Integer id) {
        /** 通过Id获得本条数据的信息*/
        MakeSheet makeSheet = makeSheetRepository.getOne(id);

        /** 拼接Sql的参数*/
        List<Integer> listId = new ArrayList<>();
        listId.add(id);

        /** 通过主表Id查询出plan表里面的未提交的明细数据*/
        List<String> planDrawNoList = makePlanMapper.findNotSubmitPlan(listId);

        /** 通过主表Id查询出Change表里面的变更的未提交的明细数据*/
        List<MakeChange> changeList = makeChangeMapper.findNotSubmitChange(listId);

        /** 存放变更表里面的未提交的修改过图号和新增图号的数据LIst初始化*/
        List<String> changeDrawNoList = new ArrayList<>();

        /** 将不需要的图号过滤掉*/
        for (MakeChange makeChange : changeList) {
            /** 判断是修改的还是新增的数据TechnologyChange：1=修改数据，3=新增数据*/
            if(makeChange.getTechnologyChange()==1){
                /** 判断是否是图号修改的*/
                if (!makeChange.getDrawNo().equals(makeChange.getAfterDrawNo())){
                    /** 存放变更过后的的图号*/
                    changeDrawNoList.add(makeChange.getAfterDrawNo());
                }
            }else if(makeChange.getTechnologyChange()==3){
                changeDrawNoList.add(makeChange.getAfterDrawNo());
            }
        }

        /** 通过项目号查询主表里面的已提交的但是未审核的数据的id */
        List<Integer> makeIdList = makeSheetMapper.getNotSubmitId(makeSheet.getProCode());
        /** 存放变更表里面的已提交的修改过图号和新增图号的数据*/
        List<String> submitChangeDrawNoList = new ArrayList<>();
        List<String> submitNotCheckPlanDrawNoList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(makeIdList)){
            /** 通过已提交未审核的数据Id查询出已提交但是未审核的Plan表的明细数据*/
            submitNotCheckPlanDrawNoList = makePlanMapper.findNotSubmitPlan(makeIdList);
            /** 通过主表已提交未审核的数据Id查询出Change表里面的变更的已提交未审核的明细数据*/
            List<MakeChange> submitNotCheckChangeList = makeChangeMapper.findNotSubmitChange(makeIdList);
            for (MakeChange makeChange : submitNotCheckChangeList) {
                /** 判断是否是修改的数据*/
                if(makeChange.getTechnologyChange()==1){
                    /** 判断是否是图号修改的*/
                    if (!makeChange.getDrawNo().equals(makeChange.getAfterDrawNo())){
                        /** 存放变更过后的的图号*/
                        submitChangeDrawNoList.add(makeChange.getAfterDrawNo());
                    }
                }else if(makeChange.getTechnologyChange()==3){
                    submitChangeDrawNoList.add(makeChange.getAfterDrawNo());
                }
            }
        }

        /** 通过项目编号查询makeResult表里面的数据*/
        List<String> resultDrawNOList = makeResultMapper.getCheckResultDraw(makeSheet.getProCode());
        /** 拼接明细表里的数据*/
        resultDrawNOList.addAll(planDrawNoList);
        /** 拼接变更表里面的数据*/
        resultDrawNOList.addAll(changeDrawNoList);
        /** 拼接已提交未审核的明细表里面的数据*/
        resultDrawNOList.addAll(submitNotCheckPlanDrawNoList);
        /** 拼接已提交变更表里的数据*/
        resultDrawNOList.addAll(submitChangeDrawNoList);
        /** 去重以后的长度*/
        long count = resultDrawNOList.stream().distinct().count();
        List<String> collect = new ArrayList<>();
        /** 判断是否有重复数据分别是什么*/
        if(count!=resultDrawNOList.size()){
            collect = resultDrawNOList.stream()
                    .collect(Collectors.toMap(e -> e, e -> 1, (a, b) -> a + b)) // 获得元素出现频率的 Map，键为元素，值为元素出现的次数
                    .entrySet().stream() // Set<Entry>转换为Stream<Entry>
                    .filter(entry -> entry.getValue() > 1) // 过滤出元素出现次数大于 1 的 entry
                    .map(entry -> entry.getKey()) // 获得 entry 的键（重复元素）对应的 Stream
                    .collect(Collectors.toList());// 转化为 List
        }
        return collect;

    }


    /**
     * @Author mayongfeng
     * @Date 13:38 2021/1/8
     * @Description 点击提交的时候先验证项目部分下是否有相同的图号
     *
     **/
    public List<String> getRepeatPartDrawNo(Integer id) {
        /** 通过Id获得本条数据的信息*/
        MakeSheet makeSheet = makeSheetRepository.getOne(id);
        /** 拼接Sql的参数*/
        List<Integer> listId = new ArrayList<>();
        listId.add(id);

        /** 通过主表Id查询出plan表里面的未提交的明细数据*/
        List<String> planDrawNoList = makePlanMapper.findNotSubmitPlan(listId);

        /** 通过主表Id查询出Change表里面的变更的未提交的明细数据*/
        List<MakeChange> changeList = makeChangeMapper.findNotSubmitChange(listId);

        /** 存放变更表里面的未提交的修改过图号和新增图号的数据LIst初始化*/
        List<String> changeDrawNoList = new ArrayList<>();

        /** 将不需要的图号过滤掉*/
        for (MakeChange makeChange : changeList) {
            /** 判断是修改的还是新增的数据TechnologyChange：1=修改数据，3=新增数据*/
            if(makeChange.getTechnologyChange()==1){
                /** 判断是否是图号修改的*/
                if (!makeChange.getDrawNo().equals(makeChange.getAfterDrawNo())){
                    /** 存放变更过后的的图号*/
                    changeDrawNoList.add(makeChange.getAfterDrawNo());
                }
            }else if(makeChange.getTechnologyChange()==3){
                changeDrawNoList.add(makeChange.getAfterDrawNo());
            }
        }
        /** 通过项目编号和部分查询makeResult表里面的数据*/
        List<String> resultDrawNOList = makeResultMapper.getCheckResultPartDraw(makeSheet.getProCode(),makeSheet.getPartId());
        /** 拼接明细表里的数据*/
        resultDrawNOList.addAll(planDrawNoList);

        /** 拼接变更表里面的数据*/
        resultDrawNOList.addAll(changeDrawNoList);

        /** 去重以后的长度*/
        long count = resultDrawNOList.stream().distinct().count();
        List<String> collect = new ArrayList<>();
        /** 判断是否有重复数据分别是什么*/
        if(count!=resultDrawNOList.size()){
            collect = resultDrawNOList.stream()
                    .collect(Collectors.toMap(e -> e, e -> 1, (a, b) -> a + b)) // 获得元素出现频率的 Map，键为元素，值为元素出现的次数
                    .entrySet().stream() // Set<Entry>转换为Stream<Entry>
                    .filter(entry -> entry.getValue() > 1) // 过滤出元素出现次数大于 1 的 entry
                    .map(entry -> entry.getKey()) // 获得 entry 的键（重复元素）对应的 Stream
                    .collect(Collectors.toList());// 转化为 List
        }
        return collect;
    }
}
